package pruebas.testBalas;

import org.junit.*;
import static org.junit.Assert.*;
import modelo.armas.AlcanceAgotadoException;
import modelo.armas.BalasAlgo42;
import modelo.armas.BalasEnemigas;
import modelo.armas.PickUpEnergiaCaza;
import modelo.desplazadores.DesplazadorLineaRecta;
import modelo.naves.Avioneta;
import modelo.naves.NaveAlgo42;
import modelo.util.Vector;

public class TestBalasAlgo42 {
	private int danio = 4;
	private int alcance = 5;
	private float velocidad = 1;
	private Vector p1 = new Vector(0, 0);
	private Vector p2 = (new Vector(1, 0)).multiplicar(velocidad);
	private Vector p3 = p1.sumar(p2.multiplicar(5));// mover 5 veces
	private BalasAlgo42 bala;

	@Before
	public void setUp() throws Exception {
		bala = new BalasAlgo42(danio, alcance);
		DesplazadorLineaRecta desplazador = new DesplazadorLineaRecta(p1, p2,
				velocidad);
		bala.setDesplazador(desplazador);
	}
	
	@Test
	public void testInicializacion() {
		assertEquals("posicion incorrecta en balaAlgo42", p1,
				bala.getPosicion());
		assertEquals("danio incorrecto en bala", danio, bala.getDanio());
		assertEquals("alcance incorrecto en bala", alcance, bala.getAlcance());
		assertTrue("la bala deberia estar activa al crearla", bala.activa());
		assertTrue("la bala deberia permitir seguir actuando al crearla",
				bala.seguirActuando());
	}
	
	@Test (expected = AlcanceAgotadoException.class)
	public void testMovimiento(){
		//mientras no se haya agotado el alacance debe permitir moverse
		for (int i = 0; i < alcance ; i++){
			bala.mover();
		}
		assertEquals ("movimiento incorrecto en la bala", p3, bala.getPosicion());
		//como el alcance debe estar agotado no debe permitir seguir moviendo 
		assertFalse ("no deberia permitir seguir actuando con el alcance agotado",
				bala.seguirActuando());
		bala.mover();
	}

	@Test
	public void testColisionConBalasEnemigas() {
		// las balas no deben chocarse entre si.
		BalasEnemigas unaBalaEnemiga = new BalasEnemigas(danio, alcance);
		DesplazadorLineaRecta desplazador = new DesplazadorLineaRecta(p1, p2,
				velocidad);
		unaBalaEnemiga.setDesplazador(desplazador);
		assertTrue("las balas deberian indicar que pueden llegar a chocarse",
				bala.chocaCon(unaBalaEnemiga));
		bala.chocarCon(unaBalaEnemiga);
		assertTrue("las balas no deberian chocarse entre si",
				bala.seguirActuando());
		assertTrue("las balas no deberian chocarse entre si",
				unaBalaEnemiga.seguirActuando());
	}
		
	@Test	
	public void testColisionConBalasAlgo42(){
		BalasAlgo42 unaBalaAlgo42 = new BalasAlgo42(danio, alcance);
		DesplazadorLineaRecta desplazador = new DesplazadorLineaRecta(p1, p2,
				velocidad);
		unaBalaAlgo42.setDesplazador(desplazador);
		assertTrue("las balas deberian indicar que pueden llegar a chocarse",
				bala.chocaCon(unaBalaAlgo42));
		bala.chocarCon(unaBalaAlgo42);
		assertTrue("las balas no deberian chocarse entre si",
				bala.seguirActuando());
		assertTrue("las balas no deberian chocarse entre si",
				unaBalaAlgo42.seguirActuando());

	}
	
	@Test
	public void testColisionConNavesEnemigas (){
		//las balas del algo42 deben chocar con las naves enemigas
		Avioneta nave = new Avioneta(p1, p2);
		int energiaAntesDelChoque = nave.getEnergia();
		assertTrue(
				"la nave y la bala deberian indicar que pueden llegar a chocarse",
				bala.chocaCon(nave));
		bala.chocarCon(nave);
		assertFalse("la bala no deberia poder seguir actuando",
				bala.seguirActuando());
		assertTrue("la energia de la nave deberia haberse reducido",
				nave.getEnergia() < energiaAntesDelChoque);
	}
	
	@Test
	public void testColisionConNaveAlgo42() {
		//las balas del algo42 no deben afectarlo
		NaveAlgo42 nave = new NaveAlgo42 (p1, p2);
		int energiaAntesDelChoque = nave.getEnergia();
		assertTrue(
				"la nave y la bala deberian indicar que pueden llegar a chocarse",
				bala.chocaCon(nave));
		bala.chocarCon(nave);
		assertTrue("la bala deberia poder seguir actuando",
				bala.seguirActuando());
		assertEquals("la energia de la nave no deberia haberse reducido",
				nave.getEnergia(), energiaAntesDelChoque);
	}
	
	@Test
	public void testColisionConPickUp (){
		// las balas y los pickUp no deben afectarse
		PickUpEnergiaCaza pickUp = new PickUpEnergiaCaza(p1, p2);
		// CAMBIAR
		assertTrue ("la bala y el pickUp deberian indicar que pueden chocarse",
				bala.chocaCon(pickUp));
		assertTrue ("la bala deberia poder seguir actuando", 
				bala.seguirActuando());
		assertTrue ("el pickUp deberia poder seguir actuando",
				pickUp.seguirActuando());
	}
	
}
